home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / filesy~1 / mfs609s.zoo / minixfs / dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-25  |  3.4 KB  |  140 lines

  1. /* This file is part of 'minixfs' Copyright 1991,1992,1993 S.N.Henson */
  2.  
  3. #include "minixfs.h"
  4. #include "proto.h"
  5. #include "global.h"
  6.  
  7.  
  8. /* search_dir serves 3 functions dependent on 'mode'
  9. 0 Search a directory for the entry 'name' if found return its inode number.
  10. 1 Create an entry 'name' return position of d_inum .
  11. 2 Delete an entry 'name' return inode num for success .
  12. 3 Find entry 'name', return position of d_inum.
  13. In all cases failure is denoted by a negative error number .
  14. */
  15.  
  16. long search_dir(name,inum,drive,flag)
  17. const char *name;
  18. unsigned inum;
  19. int drive;
  20. int flag;
  21. {
  22.     int entry,count;
  23.     long zone;        /* Zone number within dir */
  24.     long lstfree;    /* Last unused dir entry */
  25.     d_inode rip;
  26.     bufr *tmp;
  27.     int tflag;
  28.     int incr;
  29.     int mfname;
  30.     static char tname[MNAME_MAX];
  31.  
  32.     incr=super_ptr[drive]->increment;
  33.     mfname=MMAX_FNAME(incr);
  34.  
  35.     if( (tflag=do_trans(SRCH_TOS,drive)) )
  36.                 strcpy(tname,tosify(name,tflag,mfname));
  37.  
  38.     read_inode(inum,&rip,drive);
  39.     /* Must be a directory ! */
  40.     if(!IS_DIR(rip)) return EPTHNF;
  41.  
  42.     lstfree=-1l;
  43.     for(zone=0; (count=cnext_zone(&rip,zone,&tmp,drive)>>L_DIR_SIZE);
  44.     zone++)
  45.     {
  46.     dir_struct *try;
  47.         for(entry=0,try=tmp->bdir;entry<count;entry+=incr,try+=incr) {
  48.              unshort inumtemp;
  49.              inumtemp=try->d_inum;
  50.              if(inumtemp &&
  51.             (!strncmp(name,try->d_name,mfname) || (tflag && 
  52.         (!strcmp(tname,tosify(try->d_name,tflag,mfname)) ) )))
  53.  
  54.             {
  55.                 if(flag==KILL)
  56.             {
  57.                   /* Never ever allow unlinking of '.' or '..' */
  58.                   if(zone==0 && entry<2)return EACCDN;
  59.                       try->d_inum=0;
  60.  
  61.             /* Next bit pinched from Minix,
  62.              * store old inode num in last 2 bytes of name
  63.              * This allows recovery in case of accident
  64.              */
  65.         *((unshort *)&try->d_name[MMAX_FNAME(incr)-2])=inumtemp;
  66.  
  67.                 write_zone(find_zone(&rip,zone,drive,0),tmp
  68.                 ,drive,&syscache);
  69.                 }
  70.             if(flag==ADD) return  EACCDN;
  71.         if(flag==FIND || flag==KILL ) return inumtemp;
  72.             if(flag==POS) return entry*DIR_ENTRY_SIZE+zone*BLOCK_SIZE;
  73.         }
  74.             if(lstfree==-1l && !inumtemp)
  75.             lstfree=zone*BLOCK_SIZE+entry*DIR_ENTRY_SIZE;
  76.         }
  77.     }
  78.  
  79.     if(flag==ADD) {
  80.     dir_struct add[MAX_INCREMENT];
  81.     strncpy(tname,name,mfname );
  82.     tname[mfname]=0;
  83.     if(badname(tname)) return EACCDN;
  84.     if( do_trans(LWR_TOS,drive) ) Strlwr(tname);
  85.           strncpy(add[0].d_name,tname,mfname);
  86.     add[0].d_inum=0;
  87.     if(l_write(inum,lstfree,(long)(mfname+2),add,drive)
  88.             !=(mfname+2) ) return EACCDN;
  89.     return( lstfree==-1l ? rip.i_size : lstfree);
  90.     }
  91.     return EFILNF;
  92. }
  93.  
  94. /* Return '1' if 'name' has any illegal characters in it */
  95.  
  96. int badname(name)
  97. char *name;
  98. {
  99.     if(!*name)
  100.     {
  101.         DEBUG("Minixfs: Illegal null filename");
  102.         return 1;
  103.     }
  104.     for(;*name;name++) if(BADCHR(*name)) 
  105.     {
  106.         DEBUG("minixfs: Bad character in filename");
  107.         return 1;
  108.     }
  109.     return 0;
  110. }
  111.  
  112. /* Return '1' if dir2 is a parent of dir1 , otherwise 0 or negative error 
  113.  * number 
  114.  */
  115.  
  116. long is_parent(dir1,dir2,drive)
  117. unsigned dir1,dir2;
  118. int drive;
  119. {
  120.     long itemp=dir1;
  121.     for(;;)
  122.     {
  123.         if(itemp==dir2)
  124.         {
  125.             DEBUG("minixfs: invalid directory move");
  126.             return 1;
  127.         }
  128.         if(itemp==ROOT_INODE)break;
  129.         itemp=search_dir("..",itemp,drive,FIND);
  130.         if(itemp < 0)
  131.         {
  132.             ALERT("Couldn't trace inode %d back to root",dir1);
  133.             return EACCDN;
  134.         }    
  135.     }
  136.     return 0;
  137. }
  138.  
  139.  
  140.